package com.daJiao.filter;

import cn.hutool.json.JSONUtil;
import com.daJiao.constants.Constants;
import com.daJiao.constants.RedisKeyPrefix;
import com.daJiao.domain.SecurityUserDetails;
import com.daJiao.exception.BusinessException;
import com.daJiao.handler.security.CustomerLoginAuthEntryPoint;
import com.daJiao.utils.SpringContextHolder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * <p>Title:      CustomerAuthenticationFilter. </p>
 * <p>Description TODO </p>
 * <p>Copyright: Copyright (c) 2016</p>
 * <p>Company:    医百科技有限公司 </p>
 *
 * @author <a href="yangwensheng@100doc.com.cn"/>杨文生</a>
 * @since 2020/9/20 23:07
 */
public class CustomerAuthenticationFilter extends BasicAuthenticationFilter {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private CustomerLoginAuthEntryPoint customerLoginAuthEntryPoint;

    public CustomerAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            String header = request.getHeader(Constants.BEARER_AUTHENTICATION);
            //当token为空或格式错误时 直接放行
            if (header == null || !header.startsWith(Constants.BEARER_AUTHENTICATION)) {
                chain.doFilter(request, response);
                return;
            }

            UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(header);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            chain.doFilter(request, response);
    }


    private UsernamePasswordAuthenticationToken getAuthentication(String header) {
        String token = header.replace(Constants.BEARER_AUTHENTICATION, "");
        if (redisTemplate == null) {
            redisTemplate = SpringContextHolder.getBean("redisTemplate");
        }
        ValueOperations operations = redisTemplate.opsForValue();
        Object obj = operations.get(RedisKeyPrefix.ONLINEUSER + token);
        if (obj == null) {
           throw new BusinessException("无效的token");
        }
        SecurityUserDetails securityUser = JSONUtil.toBean(obj.toString(), SecurityUserDetails.class);
        return new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities());
    }

}
